package com.moody.calculator;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.moody.hibernate.domain.ReportData;
import com.moody.hibernate.domain.ReportList;
import com.moody.init.ReportModelInit;
import com.moody.service.CustomerService;
import com.moody.service.impl.CustomerServiceImpl;

/*
 * Copyright ? Moody analytics   
 *
 * @Title: EnterBalanceCheck.java 
 * @Package： com.moody.calculator 
 * @author： Liu Peng
 * @Description: 会企资产负债表校验
 * @date： 2012-2-28 下午12:25:55
 * @Modified by: Liu Peng 
 * @version V1.0   
 */

public class EnterCheck {
	private static final Logger log = LoggerFactory.getLogger(EnterCheck.class);
	
	private Map<String,Double> valueMap;
	private Map<String,String> nameMap;
	private Map<String,String> checkMap;
	private List<ReportData> reportDataList = null;
	boolean isComplete;
	private List<String> resultList;
	
	public EnterCheck(List<ReportData> reportDataList){
		this.reportDataList = reportDataList;
		isComplete = true;
		valueMap = new HashMap<String,Double>();
		nameMap = ReportModelInit.getInstance().getDisplayNameMap();
		checkMap = new HashMap<String,String>();
		resultList = new LinkedList<String>();

		initValueMap();
		initCheckMap();
	}
	
	public List<String> check(){
		checkNegative();
		checkBalance();
		
		return resultList;
	}
	
	private void initValueMap(){
		if(reportDataList != null){
			for(ReportData rd : reportDataList){
//				if(rd.getItemValue() == null && isComplete){
//					isComplete = false;
//					resultList.add("报表完整性检查:报表不完整");
//				}
				valueMap.put(rd.getReportItemNo(), rd.getItemValue());
			}
		}
	}
	
	//判断double类型是否为0
	public Boolean isZero(Double data){
		if(data!=null && (data >10E-6 || data <-(10E-6)))
			return false;
		else
			return true;
	}
	//判断double类型是否小于0
	public Boolean isNegative(Double data){
		if(data!=null && data <-(10E-6))
			return true;
		else
			return false;
	}
	
	public void checkBalance(){
		DecimalFormat df = new DecimalFormat("###,##0.00");
		Set<String> keySet = checkMap.keySet();
		for(String sumKey :keySet){
			boolean lostItem = false;
			if(!valueMap.containsKey(sumKey)) continue;
			String[] itemArray = checkMap.get(sumKey).split(",");
			double res = 0;
			for(String itemKey : itemArray){
				double value = 0;
				if(itemKey.substring(0, 1).equals("-")) {
					if(valueMap.containsKey(itemKey.substring(1)))value =  valueMap.get(itemKey.substring(1)) * -1;
					else lostItem = true;
				}
				else {
					if(valueMap.containsKey(itemKey))value = valueMap.get(itemKey);
					else lostItem = true;
				}
				if(lostItem) break;
				res += value; 
			}
			if(lostItem) continue;
			
			res = valueMap.get(sumKey) - res;
			
			BigDecimal bd = new BigDecimal(res);
			res = bd.setScale(6, BigDecimal.ROUND_HALF_UP).doubleValue();
			
			if(Math.abs(res) > 10E-6){
				String itemList = "";
				if(itemArray.length == 1){
					itemList = nameMap.get(itemArray[0]);
				}
				else{
					itemList = "(";
					for(String itemKey : itemArray){
						if(itemKey.substring(0, 1).equals("-")) {
							if(itemList.length() > 1) itemList += " -";
							itemList += " " + nameMap.get(itemKey.substring(1));
						}
						else {
							if(itemList.length() > 1) itemList += " +";
							itemList += " " + nameMap.get(itemKey);
						}
					}
					itemList += ")";
				}
				
				String title = "";
				if(sumKey.contains("BS")) title = "资产负债表：";
				else if(sumKey.contains("EIS")) title = "利润表：";
				else if(sumKey.contains("PIS")) title = "收入支出表：";
				else if(sumKey.contains("FIS")) title = "损益表：";
				else if(sumKey.contains("CF")) title = "现金流量表：";
				resultList.add(title + nameMap.get(sumKey) +" - " + itemList +" = " + df.format(res));
				
			}
		}
	}
	//资产负债表：非负数检查
	public boolean checkNegative(){
		boolean flag = true;
		Double ECF001 = valueMap.get("ECF001");//销售产品、提供劳务收到的现金
		Double EBS041 = valueMap.get("EBS041");//资产总计
		Double E01001 = 0.0;
		if(valueMap.get("EBS041")!=null && valueMap.get("EBS035")!=null ){		
			E01001 = valueMap.get("EBS041") - valueMap.get("EBS035");//有形资产总额＝资产总额－无形资产
		}
		Double EBS069 = valueMap.get("EBS069");//所有者权益
		Double EBS008 = valueMap.get("EBS008");//存货
		Double EBS068 = valueMap.get("EBS068");//负债总计
		Double EBS079 = valueMap.get("EBS079");//负债和所有者权益总计
		Double E01002 = 0.0;
		if(valueMap.get("EBS061")!=null && valueMap.get("EBS063")!=null && valueMap.get("EBS064")!=null){
			E01002 = valueMap.get("EBS061") + valueMap.get("EBS063") + valueMap.get("EBS064");//长期有息债务 = 长期借款＋应付债券＋长期应付款
		}
		Double EBS043 = valueMap.get("EBS043");//流动负债合计
		
		if(isNegative(ECF001)){
			resultList.add("现金流量表：销售产品、提供劳务收到的现金  < 0");
			flag = false;
		}
		if(isNegative(EBS041) || isZero(EBS041)){
			resultList.add("资产负债表：资产总计  <= 0");
			flag = false;
		}
		if(isNegative(E01001)){
			resultList.add("资产负债表：有形资产总额（资产总额－无形资产）  < 0");
			flag = false;
		}
		if(isZero(EBS069)){
			resultList.add("资产负债表：所有者权益  = 0");
			flag = false;
		}
		if(isNegative(EBS008)){
			resultList.add("资产负债表：存货  < 0");
			flag = false;
		}
		if(isNegative(EBS068)){
			resultList.add("资产负债表：负债总计  < 0");
			flag = false;
		}
		if(isNegative(E01002)){
			resultList.add("资产负债表：长期有息债务（长期借款＋应付债券＋长期应付款） < 0");
			flag = false;
		}
		if(isNegative(EBS043)){
			resultList.add("资产负债表：流动负债合计  < 0");
			flag = false;
		}
		
		//资产 - 负债
		if(EBS041 != null && EBS079 != null){
			Double res = EBS041 - EBS079;
			BigDecimal bd = new BigDecimal(res);
			res = bd.setScale(6, BigDecimal.ROUND_HALF_UP).doubleValue();
			if(Math.abs(res) > 10E-6){
				resultList.add("资产负债表：资产总计 - 负债和所有者权益总计  = " + new DecimalFormat("###,##0.00").format(res));
				flag = false;
			}
		}
		
		return flag;
		
		
	}
	
	private void initCheckMap(){
		checkMap.put("EBS003","EBS005,EBS006,EBS013,EBS007,EBS014,EBS015,EBS016,EBS017,EBS008,EBS011,EBS012,EBS018");
		checkMap.put("EBS019","EBS021,EBS022,EBS023,EBS024,EBS025,EBS020,EBS029,EBS030,EBS031,EBS032,EBS034,EBS035,EBS036,EBS037,EBS038,EBS039,EBS040");
		checkMap.put("EBS041","EBS003,EBS019");
		checkMap.put("EBS043","EBS045,EBS046,EBS049,EBS047,EBS050,EBS051,EBS052,EBS053,EBS054,EBS055,EBS056,EBS057,EBS058,EBS059");
		checkMap.put("EBS060","EBS061,EBS063,EBS064,EBS065,EBS066,EBS067");
		checkMap.put("EBS068","EBS043,EBS060");
		checkMap.put("EBS069","EBS070,EBS072,EBS073,EBS076,-EBS077");
		checkMap.put("EBS079","EBS068,EBS069");

		checkMap.put("EIS012","EIS001,-EIS002,-EIS003,-EIS004,-EIS005,-EIS026,-EIS006,EIS008,EIS007");
		checkMap.put("EIS016","EIS012,EIS013,-EIS015");
		checkMap.put("EIS019","EIS016,-EIS017");
	
		checkMap.put("ECF005", "ECF001,ECF003,ECF004");
		checkMap.put("ECF013", "ECF006,ECF008,ECF009,ECF012");
		checkMap.put("ECF014", "ECF005,-ECF013");
		checkMap.put("ECF020", "ECF015,ECF016,ECF018,ECF017,ECF019");
		checkMap.put("ECF025", "ECF021,ECF022,ECF023,ECF024");
		checkMap.put("ECF026", "ECF020,-ECF025");
		checkMap.put("ECF032", "ECF027,ECF030,ECF031");
		checkMap.put("ECF042", "ECF034,ECF035,ECF041");
		checkMap.put("ECF043", "ECF032,-ECF042");
		checkMap.put("ECF045", "ECF014,ECF026,ECF043,ECF044");
		checkMap.put("ECF070", "ECF045,ECF071");

		
		
	}
}
